home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 May: Tool Chest / Dev.CD May 98 TC.toast / Tool Chest / Development Kits / HyperCard Related / APDA HyperCard Toolkits / CD Audio Toolkit 1.0 / Source / CDPlay.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-07  |  9.6 KB  |  371 lines  |  [TEXT/MPS ]

  1. /*
  2.     CDPlay - An XFCN to play absolute minute, second, block
  3.     ©Apple Computer, Inc. 1988
  4.     All Rights Reserved.
  5.     
  6.     88/10/08    BL°B    First Version
  7.  
  8.     To compile and link this file using Macintosh Programmer's Workshop,
  9.  
  10.     C -q2 CDPlay.c
  11.     link -sn Main=CDPlay -sn STDIO=CDPlay ∂
  12.          -sn INTENV=CDPlay -rt XFCN=42 ∂
  13.          -m CDPLAY CDPlay.c.o "{CLibraries}"CRuntime.o ∂
  14.          "{CLibraries}"StdCLib.o ∂
  15.          -o HyperCommands
  16.          
  17.     This link directive puts the XCMD in the file "HyperCommands".
  18.     Substitute the name of the stack you want it in.  To move XCMDs
  19.     between stacks, use ResEdit.  They can be in an individual stack,
  20.     the Home stack, the HyperCard application, or the System File.
  21.     
  22. */
  23.  
  24. #include <cd.h>
  25.  
  26. /* prototype definitions for functions */
  27. void    ExtractBCD(char *, short *);
  28. OSErr    APlay(XCmdBlockPtr, short, short, short, short);
  29. OSErr    BCDPosition(short, short *, short *, short *);
  30. OSErr    AStop(XCmdBlockPtr, short, short, short, short);
  31. OSErr    FindTrack1BCD(short, short *, short *, short *);
  32.  
  33. /* **** WARNING:  DO NOT USE GLOBAL VARIABLES! **** */
  34.  
  35.  
  36. /************************************************************************
  37.  *
  38.  *  Function:        CDPlay
  39.  *
  40.  *  Purpose:        play absolute minute, second and block
  41.  *
  42.  *  Returns:        result of driver call to play
  43.  *                    normally 0, but could have parameter error or
  44.  *                    other error if non-existent block is specified
  45.  *
  46.  *  Side Effects:
  47.  *
  48.  *  Description:    We need three parameters or no parameters:
  49.  *                    1) the minute
  50.  *                    2) the second
  51.  *                    3) the block
  52.  *                    Extract the minute, second and block and start
  53.  *                    playing at that point.
  54.  *                    If we don't get any parameters, start play at the
  55.  *                    current position.
  56.  *
  57.  *                    We may also get three additional parameters which 
  58.  *                    specify the stop address.   If so, set up a stop
  59.  *                    at that address.
  60.  *
  61.  ************************************************************************/
  62. pascal void
  63. CDPlay(paramPtr)
  64. XCmdBlockPtr    paramPtr;
  65. {
  66.     Str31    returnString;
  67.     OSErr    result;
  68.     short    minute;
  69.     short    second;
  70.     short    block;
  71.     short    ioRefNum;
  72.     Handle    refHandle;
  73.     
  74.     /* Get the global ioRefNum and convert it. */
  75.     refHandle = GetGlobal(paramPtr, GLOBALNAME);
  76.     ioRefNum = atoi(*(refHandle));
  77.     DisposHandle(refHandle);
  78.     ioRefNum &= 0xFFFF;            /* remove vRefNum; not needed. */
  79.  
  80.     /* Must be three parameters, or none (or six) */
  81.     switch (paramPtr->paramCount) {
  82.         case 0:
  83.             result = BCDPosition(ioRefNum, &minute, &second, &block);
  84.     
  85.             if (result == noErr)
  86.                 result = APlay(paramPtr, ioRefNum, minute, second, block);
  87.             
  88.             if (result == paramErr)
  89.             {    /* we're trying to play an invalid position.
  90.                 ** find the start of track 1, and try to play there. */
  91.                 
  92.                 result = FindTrack1BCD(ioRefNum, &minute, &second, &block);
  93.                 
  94.                 if (result == noErr)
  95.                     result = APlay(paramPtr, ioRefNum, minute, second, block);
  96.             }
  97.             break;
  98.         case 3:
  99.             /* First param is minute.  Convert it to a BCD number */
  100.             ExtractBCD((char *)*(paramPtr->params[0]), &minute);
  101.             
  102.             /* Second param is second.  Convert it to a BCD number */
  103.             ExtractBCD((char *)*(paramPtr->params[1]), &second);
  104.             
  105.             /* Third param is block.  Convert it to a BCD number */
  106.             ExtractBCD((char *)*(paramPtr->params[2]), &block);
  107.             
  108.             result = APlay(paramPtr, ioRefNum, minute, second, block);
  109.             break;
  110.         case 6:
  111.             /* fourth param is minute.  Convert it to a BCD number */
  112.             ExtractBCD((char *)*(paramPtr->params[3]), &minute);
  113.             
  114.             /* fifth param is second.  Convert it to a BCD number */
  115.             ExtractBCD((char *)*(paramPtr->params[4]), &second);
  116.             
  117.             /* sixth param is block.  Convert it to a BCD number */
  118.             ExtractBCD((char *)*(paramPtr->params[5]), &block);
  119.             
  120.             result = AStop(paramPtr, ioRefNum, minute, second, block);
  121.             if (result == noErr)
  122.             {
  123.                 /* First param is minute.  Convert it to a BCD number */
  124.                 ExtractBCD((char *)*(paramPtr->params[0]), &minute);
  125.                 
  126.                 /* Second param is second.  Convert it to a BCD number */
  127.                 ExtractBCD((char *)*(paramPtr->params[1]), &second);
  128.                 
  129.                 /* Third param is block.  Convert it to a BCD number */
  130.                 ExtractBCD((char *)*(paramPtr->params[2]), &block);
  131.                 
  132.                 result = APlay(paramPtr, ioRefNum, minute, second, block);
  133.             }
  134.             break;
  135.         default:
  136.             /* Report error in parameters by returning -1 */
  137.             result = -1;
  138.             break;
  139.     }
  140.  
  141.     /* Convert result to string & return it */
  142.     NumToStr(paramPtr, (long) result, &returnString);
  143.     paramPtr->returnValue = PasToZero(paramPtr, (StringPtr) &returnString);
  144. }
  145.  
  146. /************************************************************************
  147.  *
  148.  *  Function:        ExtractBCD
  149.  *
  150.  *  Purpose:        Extract number in BCD from PString
  151.  *
  152.  *  Returns:        nothing
  153.  *
  154.  *  Side Effects:    *track gets a new value
  155.  *
  156.  *  Description:    Extract number in BCD from Cstring "name".
  157.  *                    "name" is always of the form "XX", where XX
  158.  *                    ranges from "1"  to "99"
  159.  *
  160.  ************************************************************************/
  161. void
  162. ExtractBCD(name, number)
  163. char        *name;
  164. short        *number;
  165. {
  166.     short    t;
  167.         
  168.     t = 0;
  169.     while (*name != 0)
  170.     {
  171.         t *= 16;
  172.         t += *name - '0';
  173.         name++;
  174.     }
  175.     
  176.     *number = t;    
  177. }
  178.  
  179. /************************************************************************
  180.  *
  181.  *  Function:        APlay
  182.  *
  183.  *  Purpose:        start playing at an absolute minute, second, block
  184.  *
  185.  *  Returns:        OSErr.  Probably either
  186.  *                        noErr        everything's hunky-dory!
  187.  *                        paramErr    you messed up the call somehow.
  188.  *
  189.  *  Side Effects:    starts play.  By default, this will play until the
  190.  *                    end of the disc.
  191.  *
  192.  *  Description:    pass in the absolute minute, second and block in BCD.
  193.  *
  194.  ************************************************************************/
  195. OSErr
  196. APlay(paramPtr, refNum, minute, second, block)
  197. XCmdBlockPtr    paramPtr;
  198. short    refNum;
  199. short    minute;
  200. short    second;
  201. short    block;
  202. {
  203.     CDPlayParam    myPB;
  204.     short        playMode;
  205.     Handle        refHandle;
  206.     
  207.     /* Get the global ioRefNum and convert it. */
  208.     refHandle = GetGlobal(paramPtr, PLAYMODE);
  209.     playMode = atoi(*(refHandle));
  210.     DisposHandle(refHandle);
  211.     
  212.     myPB.ioCompletion = 0;
  213.     myPB.ioNamePtr = (char *) 0;
  214.     myPB.ioVRefNum = 1;
  215.     myPB.ioCRefNum = refNum;
  216.     myPB.csCode = APLAY;
  217.     
  218.     myPB.addrFormat = AMSFADDR;
  219.     myPB.unused = 0;            /* must be in BCD */
  220.     myPB.minute = (char) minute;    /* must be in BCD */
  221.     myPB.second = (char) second;    /* must be in BCD */
  222.     myPB.block = (char) block;    /* must be in BCD */
  223.     myPB.stopAddress = 0;
  224.     myPB.playMode = playMode;
  225.     return (PBControl(&myPB, false));
  226. }
  227.  
  228.  
  229. /************************************************************************
  230.  *
  231.  *  Function:        BCDPosition
  232.  *
  233.  *  Purpose:        return BCD minute, second, block position
  234.  *
  235.  *  Returns:        OSErr.  Probably either
  236.  *                        noErr        everything's hunky-dory!
  237.  *                        paramErr    you messed up the call somehow.
  238.  *
  239.  *  Side Effects:    none
  240.  *
  241.  *  Description:    Simply call the driver with a READQ call.  
  242.  *                    The absolute minute, second, block come back in 
  243.  *                    BCD.  Return them.
  244.  *
  245.  ************************************************************************/
  246. OSErr
  247. BCDPosition(refNum, minute, second, block)
  248. short    refNum;
  249. short    *minute;
  250. short    *second;
  251. short    *block;
  252. {
  253.     CDParam    myPB;
  254.     OSErr    result;
  255.     
  256.     myPB.ioCompletion = 0;
  257.     myPB.ioNamePtr = (char *) 0;
  258.     myPB.ioVRefNum = 1;
  259.     myPB.ioCRefNum = refNum;
  260.     myPB.csCode = READQ;
  261.     
  262.     result = PBControl(&myPB, false);
  263.     
  264.     if (result == noErr)
  265.     {
  266.         *minute = (short) myPB.csParam[6];
  267.         *second = (short) myPB.csParam[7];
  268.         *block = (short) myPB.csParam[8];
  269.     }
  270.     return result;
  271. }
  272.  
  273.  
  274. /************************************************************************
  275.  *
  276.  *  Function:        AStop
  277.  *
  278.  *  Purpose:        stop playing at an absolute minute, second, block
  279.  *
  280.  *  Returns:        OSErr.  Probably either
  281.  *                        noErr        everything's hunky-dory!
  282.  *                        paramErr    you messed up the call somehow.
  283.  *
  284.  *  Side Effects:    stops play.
  285.  *
  286.  *  Description:    pass in the absolute minute, second and block in BCD.
  287.  *
  288.  ************************************************************************/
  289. OSErr
  290. AStop(paramPtr, refNum, minute, second, block)
  291. XCmdBlockPtr    paramPtr;
  292. short    refNum;
  293. short    minute;
  294. short    second;
  295. short    block;
  296. {
  297.     CDPlayParam    myPB;
  298.     short        playMode;
  299.     Handle        refHandle;
  300.     
  301.     /* Get the global ioRefNum and convert it. */
  302.     refHandle = GetGlobal(paramPtr, PLAYMODE);
  303.     playMode = atoi(*(refHandle));
  304.     DisposHandle(refHandle);
  305.     
  306.     myPB.ioCompletion = 0;
  307.     myPB.ioNamePtr = (char *) 0;
  308.     myPB.ioVRefNum = 1;
  309.     myPB.ioCRefNum = refNum;
  310.     myPB.csCode = ASTOP;
  311.     
  312.     myPB.addrFormat = AMSFADDR;
  313.     myPB.unused = 0;
  314.     myPB.minute = (char) minute;    /* must be in BCD */
  315.     myPB.second = (char) second;    /* must be in BCD */
  316.     myPB.block = (char) block;        /* must be in BCD */
  317.     myPB.stopAddress = 0;
  318.     myPB.playMode = playMode;
  319.     return (PBControl(&myPB, false));
  320. }
  321.  
  322.  
  323. /************************************************************************
  324.  *
  325.  *  Function:        FindTrack1BCD
  326.  *
  327.  *  Purpose:        return start of track 1 in BCD
  328.  *
  329.  *  Returns:        OSErr.  Probably either
  330.  *                        noErr        everything's hunky-dory!
  331.  *                        paramErr    you messed up the call somehow.
  332.  *
  333.  *  Side Effects:    modifies "minute", "second", and "block" to indicate
  334.  *                    start of track 1.
  335.  *
  336.  *  Description:    Simply call the driver and return the values
  337.  *                    byte that the driver gives us.  See the developer's
  338.  *                    guide for information about the READTOC command.
  339.  *
  340.  ************************************************************************/
  341. OSErr
  342. FindTrack1BCD(refNum, minute, second, block)
  343. short    refNum;
  344. short    *minute;
  345. short    *second;
  346. short    *block;
  347. {
  348.     CDPlay3Param    myPB;
  349.     OSErr    result;
  350.     char    track[4];
  351.     
  352.     myPB.ioCompletion = 0;
  353.     myPB.ioNamePtr = (char *) 0;
  354.     myPB.ioVRefNum = 1;
  355.     myPB.ioCRefNum = refNum;
  356.     myPB.csCode = READTOC;
  357.     myPB.readType = 3;
  358.     myPB.bufAddr = track;
  359.     myPB.bufferLength = 4;
  360.     myPB.track = 1;
  361.     
  362.     result = PBControl(&myPB, false);
  363.     *minute = (short) track[1];
  364.     *second = (short) track[2];
  365.     *block = (short) track[3];
  366.     return result;
  367. }
  368.  
  369. /* C routines for HyperCard callbacks */
  370. #include <XCmdGlue.inc.c>
  371.